{{#models}}
{{#model}}
{{>partial_header}}

#' {{classname}} Class
#'
{{#vars}}
#' @field {{baseName}} {{title}}
{{/vars}}
#'
#' @importFrom R6 R6Class
#' @importFrom jsonlite fromJSON toJSON
#' @export
{{classname}} <- R6::R6Class(
  '{{classname}}',
  public = list(
    {{#vars}}
    `{{{baseName}}}` = NULL,
    {{/vars}}
    initialize = function({{#vars}}`{{baseName}}`{{#hasMore}}, {{/hasMore}}{{/vars}}){
      {{#vars}}
      if (!missing(`{{baseName}}`)) {
        {{^isListContainer}}
        {{#isInteger}}
        stopifnot(is.numeric(`{{baseName}}`), length(`{{baseName}}`) == 1)
        {{/isInteger}}
        {{#isLong}}
        stopifnot(is.numeric(`{{baseName}}`), length(`{{baseName}}`) == 1)
        {{/isLong}}
        {{#isFloat}}
        stopifnot(is.numeric(`{{baseName}}`), length(`{{baseName}}`) == 1)
        {{/isFloat}}
        {{#isDouble}}
        stopifnot(is.numeric(`{{baseName}}`), length(`{{baseName}}`) == 1)
        {{/isDouble}}
        {{#isString}}
        stopifnot(is.character(`{{baseName}}`), length(`{{baseName}}`) == 1)
        {{/isString}}
        {{#isDate}}
        stopifnot(is.character(`{{baseName}}`), length(`{{baseName}}`) == 1)
        {{/isDate}}
        {{#isDateTime}}
        stopifnot(is.character(`{{baseName}}`), length(`{{baseName}}`) == 1)
        {{/isDateTime}}
        {{^isPrimitiveType}}
        stopifnot(R6::is.R6(`{{baseName}}`))
        {{/isPrimitiveType}}
        {{/isListContainer}}
        {{#isListContainer}}
        {{#isPrimitiveType}}
        stopifnot(is.list(`{{baseName}}`), length(`{{baseName}}`) != 0)
        lapply(`{{baseName}}`, function(x) stopifnot(is.character(x)))
        {{/isPrimitiveType}}
        {{^isPrimitiveType}}
        stopifnot(is.list(`{{baseName}}`), length(`{{baseName}}`) != 0)
        lapply(`{{baseName}}`, function(x) stopifnot(R6::is.R6(x)))
        {{/isPrimitiveType}}
        {{/isListContainer}}
        self$`{{baseName}}` <- `{{baseName}}`
      }
      {{/vars}}
    },
    toJSON = function() {
      {{classname}}Object <- list()
      {{#vars}}
      if (!is.null(self$`{{baseName}}`)) {
        {{classname}}Object[['{{baseName}}']] <- {{#isListContainer}}{{#isPrimitiveType}}self$`{{baseName}}`{{/isPrimitiveType}}{{^isPrimitiveType}}lapply(self$`{{baseName}}`, function(x) x$toJSON()){{/isPrimitiveType}}{{/isListContainer}}{{^isListContainer}}self$`{{baseName}}`{{^isPrimitiveType}}$toJSON(){{/isPrimitiveType}}{{/isListContainer}}
      }
      {{/vars}}

      {{classname}}Object
    },
    fromJSON = function({{classname}}Json) {
      {{classname}}Object <- jsonlite::fromJSON({{classname}}Json)
      {{#vars}}
      if (!is.null({{classname}}Object$`{{baseName}}`)) {
        {{#isPrimitiveType}}
        self$`{{baseName}}` <- {{classname}}Object$`{{baseName}}`
        {{/isPrimitiveType}}
        {{^isPrimitiveType}}
        {{#isListContainer}}
        self$`{{baseName}}` <- lapply({{classname}}Object$`{{baseName}}`, function(x) {
          {{baseName}}Object <- {{datatype}}$new()
          {{baseName}}Object$fromJSON(jsonlite::toJSON(x, auto_unbox = TRUE))
          {{baseName}}Object
        })
        {{/isListContainer}}
        {{^isListContainer}}
        {{baseName}}Object <- {{datatype}}$new()
        {{baseName}}Object$fromJSON(jsonlite::toJSON({{classname}}Object${{baseName}}, auto_unbox = TRUE))
        self$`{{baseName}}` <- {{baseName}}Object
        {{/isListContainer}}
        {{/isPrimitiveType}}
      }
      {{/vars}}
    },
    toJSONString = function() {
       sprintf(
        '{
           {{#vars}}
           "{{baseName}}": {{#isListContainer}}[{{/isListContainer}}{{#isPrimitiveType}}{{#isNumeric}}%d{{/isNumeric}}{{^isNumeric}}%s{{/isNumeric}}{{/isPrimitiveType}}{{^isPrimitiveType}}%s{{/isPrimitiveType}}{{#isListContainer}}]{{/isListContainer}}{{#hasMore}},{{/hasMore}}
           {{/vars}}
        }',
        {{#vars}}
        {{#isListContainer}}
        {{#isPrimitiveType}}
        lapply(self$`{{baseName}}`, function(x) paste(paste0('"', x, '"'), sep=",")){{#hasMore}},{{/hasMore}}
        {{/isPrimitiveType}}
        {{^isPrimitiveType}}
        lapply(self$`{{baseName}}`, function(x) paste(x$toJSON(), sep=",")){{#hasMore}},{{/hasMore}}
        {{/isPrimitiveType}}
        {{/isListContainer}}
        {{^isListContainer}}
        self$`{{baseName}}`{{^isPrimitiveType}}$toJSON(){{/isPrimitiveType}}{{#hasMore}},{{/hasMore}}
        {{/isListContainer}}
        {{/vars}}
      )
    },
    fromJSONString = function({{classname}}Json) {
      {{classname}}Object <- jsonlite::fromJSON({{classname}}Json)
      {{#vars}}
      {{#isPrimitiveType}}
      self$`{{baseName}}` <- {{classname}}Object$`{{baseName}}`
      {{/isPrimitiveType}}
      {{^isPrimitiveType}}
      {{#isListContainer}}
      self$`{{baseName}}` <- lapply({{classname}}Object$`{{baseName}}`, function(x) {{datatype}}$new()$fromJSON(jsonlite::toJSON(x, auto_unbox = TRUE)))
      {{/isListContainer}}
      {{^isListContainer}}
      {{datatype}}Object <- {{datatype}}$new()
      self$`{{baseName}}` <- {{datatype}}Object$fromJSON(jsonlite::toJSON({{classname}}Object${{baseName}}, auto_unbox = TRUE))
      {{/isListContainer}}
      {{/isPrimitiveType}}
      {{/vars}}
    }
  )
)
{{/model}}
{{/models}}
